package com.ruoyi.business.tool;

import com.ruoyi.common.utils.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.text.MessageFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.TimeUnit;

/**
 * 随机数
 * @Author Alan Zhang
 * @Date 2023/2/25 14:40
 */
@Component
public class RedisIdWorker {
    /**开始时间戳*/
    private static final long BEGIN_TIMESTAMP = 1640995200L;
    /**序列号的位数*/
    private static final int COUNT_BITS = 32;
    private static final String INCR_CODE_KEY = "incr_code_key";
    @Autowired
    public RedisTemplate redisTemplate;

    public long nextId(String keyPrefix) {
        // 1.生成时间戳
        LocalDateTime now = LocalDateTime.now();
        long nowSecond = now.toEpochSecond(ZoneOffset.UTC);
        long timestamp = nowSecond - BEGIN_TIMESTAMP;
        // 2.生成序列号
        // 2.1获取当前日期，精确到天
        String data = now.format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        long count = redisTemplate.opsForValue().increment("id:" + keyPrefix + ":" + data);
        // 3.拼接并返回
        long id = timestamp << COUNT_BITS | count;
        System.out.println(id);
        return id;
    }

    public String createAutoID(String tableNameKey) {
        String datetimeKey = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMdd"));
        //这里是 Redis key的前缀，如: sys:tabieId:表名  如果不需要去掉表名也可以
        String key = MessageFormat.format("{0}:{1}:{2}",  "id",tableNameKey,datetimeKey);
        //查询 key 是否存在， 不存在返回 1 ，存在的话则自增加1
        Long autoID = redisTemplate.opsForValue().increment(key, 1);
        // 设置key过期时间, 保证每天的流水号从1开始
        if (autoID == 1L) {
            redisTemplate.expire(key, 86400, TimeUnit.SECONDS);
        }
        //加上时间戳 如果不需要 时分秒可以去掉
        //String datetime = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        String datetime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyyMMddHHmmss"));
        //这里是 6 位id，如果位数不够可以自行修改 ，下面的意思是 得到上面 key 的 值，位数为6 ，不够的话在左边补 0 ，比如  110 会变成  000110
        String value = StringUtils.leftPad(String.valueOf(autoID), 5, "0");
        System.out.println("value==="+value);
        //补位4   0001
        String value1 = String.format("%05d", autoID);
        System.out.println("value1==="+value1);
        //然后把 时间戳和优化后的 ID 拼接
        String id = MessageFormat.format("{0}{1}",  datetime,value);
        System.out.println(id);
        return id;
    }

    public String gen(){
        // 定义日期格式
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyMMdd");
        //根据当前时间获取yyMMdd格式的时间字符串
        String format = LocalDate.now().format(formatter);
        //判断是否存在key，不存在则设置1天的过期时间
        if (Boolean.FALSE.equals(redisTemplate.hasKey(format))) {
            redisTemplate.expire(format, 1, TimeUnit.DAYS);
        }
        //使用incr获取自增的订单号
        Long increment = redisTemplate.opsForValue().increment(format);
        //将订单号不足4位前缀补0，"%04d"，%0表示前缀补0，4表示补充4位，d表示数字类型
        String oderCode = String.format("%04d", increment);
        return format + oderCode;
    }


    public String incr(){
        //使用incr获取自增的订单号
        Long increment = redisTemplate.opsForValue().increment(INCR_CODE_KEY);
        //将订单号不足8位前缀补0，"%08d"，%0表示前缀补0，8表示补充8位，d表示数字类型
        String oderCode = String.format("%08d", increment);
        return oderCode;
    }
}
